/*
 * Copyright (c) 2009 VMware, Inc.
 * Copyright (c) 2009 John Pritchard, WTKX Project Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package wtkx.in;

import wtkx.Alert;
import wtkx.Application;
import wtkx.Component;
import wtkx.util.Properties;
import wtkx.wtk.ApplicationContext;
import wtkx.wtk.MessageType;
import wtkx.wtk.Point;

import java.awt.AWTEvent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Transparency;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSourceContext;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.WindowEvent;

public class Frame 
    extends java.awt.Frame 
{


    protected final Desktop applicationContext;


    public Frame(Desktop applicationContext) {
        super();
        if (null != applicationContext){
            this.applicationContext = applicationContext;

            this.enableEvents(AWTEvent.WINDOW_EVENT_MASK
                              | AWTEvent.WINDOW_STATE_EVENT_MASK);
            this.add(applicationContext.getDisplayHost());
            this.setFocusTraversalKeysEnabled(false);
            this.setBackground(null);
        }
        else
            throw new IllegalArgumentException();
    }

    @Override
    public void update(Graphics graphics) {
        this.paint(graphics);
    }

    @Override
    public void processWindowEvent(WindowEvent event) {
        super.processWindowEvent(event);

        switch(event.getID()) {
        case WindowEvent.WINDOW_OPENED:
            try {
                this.applicationContext.getDisplayHost().requestFocus();
                this.applicationContext.getApplication().startup(this.applicationContext.getDisplay(),this.applicationContext.getProperties());
            } 
            catch(Exception exception) {
                exception.printStackTrace();
                String message = exception.getMessage();
                if (message == null) {
                    message = exception.getClass().getName();
                }
                Alert.alert(MessageType.ERROR, message, this.applicationContext.getDisplay());
            }
            break;

        case WindowEvent.WINDOW_CLOSING:
            try {
                if (this.applicationContext.getApplication().shutdown(true)){
                    java.awt.Window window = event.getWindow();
                    window.setVisible(false);
                    window.dispose();
                }
            }
            catch (Exception exception) {
                exception.printStackTrace();
                Alert.alert(MessageType.ERROR, exception.getMessage(),
                            this.applicationContext.getDisplay());
            }
            break;

        case WindowEvent.WINDOW_CLOSED:
            System.exit(0);
            break;
        }
    }

    @Override
    protected void processWindowStateEvent(WindowEvent event) {
        super.processWindowStateEvent(event);

        switch(event.getID()) {
        case WindowEvent.WINDOW_ICONIFIED:
            try {
                this.applicationContext.getApplication().suspend();
            } 
            catch(Exception exception) {
                exception.printStackTrace();
                Alert.alert(MessageType.ERROR, exception.getMessage(),
                            this.applicationContext.getDisplay());
            }
            break;

        case WindowEvent.WINDOW_DEICONIFIED:
            try {
                this.applicationContext.getApplication().resume();
            }
            catch(Exception exception) {
                exception.printStackTrace();
                Alert.alert(MessageType.ERROR, exception.getMessage(),
                            this.applicationContext.getDisplay());
            }
            break;
        }
    }

    /*
     * 
     */
    protected static final String DEFAULT_TITLE = "WTKX";

    protected static final String T_ARGUMENT = "-t";
    protected static final String P_ARGUMENT = "-p";
    protected static final String X_ARGUMENT = "-x";
    protected static final String Y_ARGUMENT = "-y";
    protected static final String W_ARGUMENT = "-w";
    protected static final String H_ARGUMENT = "-h";

    public static void main(String[] args) throws Exception {

        int x = 0;
        int y = 0;
        int width = 800;
        int height = 600;
        String title = DEFAULT_TITLE;
        String applicationClassName = null;

        Properties properties = new Properties();

        for (int i = 0, n = args.length; i < n; i++) {
            String arg = args[i];

            if (arg.equals(X_ARGUMENT)) {
                String value = args[++i];
                x = Integer.parseInt(value);
            }
            else if (arg.equals(Y_ARGUMENT)) {
                String value = args[++i];
                y = Integer.parseInt(value);
            }
            else if (arg.equals(W_ARGUMENT)) {
                String value = args[++i];
                width = Integer.parseInt(value);
            }
            else if (arg.equals(H_ARGUMENT)) {
                String value = args[++i];
                height = Integer.parseInt(value);
            }
            else if (arg.equals(P_ARGUMENT)) {
                String filename = args[++i];
                properties.load(filename);
            }
            else {
                if (null == applicationClassName)
                    applicationClassName = arg;
                else {
                    String value = args[++i];
                    properties.put(arg, value);
                }
            }
        }


        Application application = null;

        if (null == applicationClassName) {
            System.out.println("Usage");
            System.out.println();
            System.out.println("  wtkx.in.Frame [-t title] [-p app.properties] ");
            System.out.println("          [-x pos] [-y pos] [-h height] [-w width]");
            System.out.println("          pkg.app.ClassName [prop-name prop-value]*");
            System.out.println();
            System.exit(1);
        } 
        else {
            Class applicationClass = Class.forName(applicationClassName);
            application = (Application)applicationClass.newInstance();
        }

        Desktop applicationContext = new Desktop(properties,application);

        Frame hostFrame = new Frame(applicationContext);

        hostFrame.setTitle(title);
        hostFrame.setLocation(x, y);
        hostFrame.setSize(width, height);
        hostFrame.setVisible(true);

        Desktop.InstallIcon(hostFrame);
    }

}
